/*
LCD1602上显示时钟与温度，实时温度超过最高温度会报警，
实时温度低于最低温度也会报警；按下K1使最高温度增加1，
按下K2使最高温度减小1，按下K3使最低温度增加1，按下K4使最低温度减小1；
按下S1记录当前时间，按下S2恢复记录时间；
*/
#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Key.h"
#include "Timer0.h"
#include "DS1302.h"
sbit DS1302_CE=P3^5;
//模块一，时钟
unsigned char KeyNum;
unsigned char Min,Sec,MiniSec;
unsigned char RunFlag;
//模块二，温度报警
sbit beep=P1^5;
float T,TShow;
char TLow,THigh;
unsigned char KeyNum;

void main()
{
	DS1302_CE=1;
	DS18B20_ConvertT();		//上电先转换一次温度，防止第一次读数据错误
	Delay(1000);			//等待转换完成
	THigh=AT24C02_ReadByte(7);	//读取温度阈值数据
	TLow=AT24C02_ReadByte(8);
	if(THigh>125 || TLow<-55 || THigh<=TLow)
	{
		THigh=26;			//如果阈值非法，则设为默认值
		TLow=15;
	}
	LCD_Init();
	
	DS1302_Init();
	LCD_ShowString(1,1,"  -  -  ");//静态字符初始化显示
	LCD_ShowString(2,1,"  :  :  ");
	LCD_ShowSignedNum(2,9,THigh,3);
	LCD_ShowSignedNum(2,13,TLow,3);
	DS1302_SetTime();//设置时间	
	Timer0_Init();
	
	while(1)
	{
		KeyNum=Key();
		
		/*温度读取及显示*/
		DS1302_CE=1;   //使时钟与温度冲突消除
		DS18B20_ConvertT();	//转换温度
		
		T=DS18B20_ReadT();	//读取温度
		if(T<0)				//如果温度小于0
		{
			LCD_ShowChar(1,9,'-');	//显示负号
			TShow=-T;		//将温度变为正数
		}
		else				//如果温度大于等于0
		{
			LCD_ShowChar(1,9,'+');	//显示正号
			TShow=T;
		}
		LCD_ShowNum(1,10,TShow,3);		//显示温度整数部分
		LCD_ShowChar(1,13,'.');		//显示小数点
		LCD_ShowNum(1,14,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
		
		
		DS1302_ReadTime();//读取时间
		
		LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年
		LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月
		LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日
		LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时
		LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分
		LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒
		/*阈值判断及显示*/
		if(KeyNum)
		{
			if(KeyNum==1)	//K1按键，THigh自增
			{
				THigh++;
				if(THigh>125){THigh=125;}
			}
			if(KeyNum==2)	//K2按键，THigh自减
			{
				THigh--;
				if(THigh<=TLow){THigh++;}
			}
			if(KeyNum==3)	//K3按键，TLow自增
			{
				TLow++;
				if(TLow>=THigh){TLow--;}
			}
			if(KeyNum==4)	//K4按键，TLow自减
			{
				TLow--;
				if(TLow<-55){TLow=-55;}
			}
			LCD_ShowSignedNum(2,9,THigh,3);	//显示阈值数据
			LCD_ShowSignedNum(2,13,TLow,3);
			AT24C02_WriteByte(7,THigh);		//写入到At24C02中保存
			Delay(5);
			AT24C02_WriteByte(8,TLow);
			Delay(5);
		}
		
					if(KeyNum==5)			//K3按键按下
		{
			AT24C02_WriteByte(0,DS1302_Time[0]);  //AT24C02_WriteByte(0,DS1302_Time[0]/10*16+DS1302_Time[0]%10);
			Delay(5);
			AT24C02_WriteByte(1,DS1302_Time[1]);	//将分秒写入AT24C02
			Delay(5);
			AT24C02_WriteByte(2,DS1302_Time[2]);  //AT24C02_WriteByte(0,DS1302_Time[0]/10*16+DS1302_Time[2]%10);
			Delay(5);															//注意此时烧录后会导致年与日出错；问题为解决
			AT24C02_WriteByte(3,DS1302_Time[3]);	
			Delay(5);
			AT24C02_WriteByte(4,DS1302_Time[4]);
			Delay(5);
			AT24C02_WriteByte(5,DS1302_Time[5]);
			Delay(5);
			AT24C02_WriteByte(6,DS1302_Time[6]);
			Delay(5);
		}
			
			if(KeyNum==6)			//K4按键按下
		{
			DS1302_Time[0]=AT24C02_ReadByte(0);	//读出AT24C02数据
			DS1302_Time[1]=AT24C02_ReadByte(1);
			DS1302_Time[2]=AT24C02_ReadByte(2);
			DS1302_Time[3]=AT24C02_ReadByte(3);
			DS1302_Time[4]=AT24C02_ReadByte(4);
			DS1302_Time[5]=AT24C02_ReadByte(5);
			DS1302_Time[6]=AT24C02_ReadByte(6);
			DS1302_SetTime();  //重新写入时间
		}
		
		
		
		
		if(T>THigh)			//越界判断
		{
			LCD_ShowString(1,16,"H");

		}
		

		else if(T<TLow)
		{
			LCD_ShowString(1,16,"L");
		}
		else
		{
			LCD_ShowString(1,16," ");
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
				if(T>THigh)
			{	
				beep=~beep;
				//延时大约1ms 通过修改此延时时间达到不同的发声效果	
			}
	
				if(T<TLow)
			{	
				beep=~beep;
				//延时大约1ms 通过修改此延时时间达到不同的发声效果	
			}			
	T0Count++;
	if(T0Count>=20)
	{
		T0Count=0;
		Key_Loop();	//每20ms调用一次按键驱动函数
	}
}
